
package guice.boot.archive.container.pipeline;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import guice.boot.archive.container.registry.ContainerServiceProvider;
import guice.boot.archive.container.service.ContainerHolder;
import guice.boot.archive.container.service.biz.BizCommandProvider;
import guice.boot.archive.container.service.biz.DefaultBizDeployer;
import guice.boot.archive.container.service.plugin.PluginCommandProvider;
import guice.boot.archive.exception.ArkRuntimeException;
import guice.boot.archive.spi.constant.Constants;
import guice.boot.archive.spi.pipeline.PipelineContext;
import guice.boot.archive.spi.pipeline.PipelineStage;
import guice.boot.archive.spi.service.PriorityOrdered;
import guice.boot.archive.spi.service.biz.BizDeployer;
import guice.boot.archive.spi.service.biz.BizFactoryService;
import guice.boot.archive.spi.service.biz.BizManagerService;
import guice.boot.archive.spi.service.event.EventService;
import guice.boot.archive.spi.service.plugin.PluginFactoryService;
import guice.boot.archive.spi.service.plugin.PluginManagerService;
import guice.boot.archive.spi.service.registry.RegistryService;
import guice.boot.archive.spi.service.session.CommandProvider;

/**
 * Handle service contained in {@link RegistryService},
 * mainly including registering service provided by ark container and service initialization
 */
@Singleton
public class RegisterServiceStage implements PipelineStage {

    @Inject
    private RegistryService registryService;

    @Override
    public void process(PipelineContext pipelineContext) throws ArkRuntimeException {
        registryDefaultService();
    }

    /**
     * Registry some default service
     */
    private void registryDefaultService() {
        /**
         * some basic container service is not allowed to be override,  they are only published
         * to be referenced by plugin and biz, even depended by other container service.
         */
        registryService.publishService(BizManagerService.class, ContainerHolder
                .getContainer().getService(BizManagerService.class), new ContainerServiceProvider(
                PriorityOrdered.HIGHEST_PRECEDENCE));
        registryService.publishService(BizFactoryService.class, ContainerHolder
                .getContainer().getService(BizFactoryService.class), new ContainerServiceProvider(
                PriorityOrdered.HIGHEST_PRECEDENCE));
        registryService.publishService(PluginManagerService.class, ContainerHolder
                .getContainer().getService(PluginManagerService.class), new ContainerServiceProvider(
                PriorityOrdered.HIGHEST_PRECEDENCE));
        registryService.publishService(PluginFactoryService.class, ContainerHolder
                .getContainer().getService(PluginFactoryService.class), new ContainerServiceProvider(
                PriorityOrdered.HIGHEST_PRECEDENCE));
        registryService.publishService(EventService.class, ContainerHolder
                .getContainer().getService(EventService.class), new ContainerServiceProvider(
                PriorityOrdered.HIGHEST_PRECEDENCE));
        registryService.publishService(RegistryService.class, ContainerHolder
                .getContainer().getService(RegistryService.class), new ContainerServiceProvider(
                PriorityOrdered.HIGHEST_PRECEDENCE));

        /**
         * some container service which may depends on other basic container service.
         */
        registryService.publishService(BizDeployer.class, new DefaultBizDeployer(),
                new ContainerServiceProvider());
        registryService.publishService(CommandProvider.class, new PluginCommandProvider(),
                Constants.PLUGIN_COMMAND_UNIQUE_ID, new ContainerServiceProvider());
        registryService.publishService(CommandProvider.class, new BizCommandProvider(),
                Constants.BIZ_COMMAND_UNIQUE_ID, new ContainerServiceProvider());
    }

}